# 导入自动化模块
from DrissionPage import ChromiumPage
# 导入序列化模块
import json
# 导入csv模块
import csv
# 导入MySQL数据库连接模块
import pymysql

# 导入配置文件
from config import DB_CONFIG, CRAWLER_CONFIG, TARGET_URL_C, CSV_CONFIG

# 中文字段名 -> 英文数据库字段名
field_map = {
    "职位": "job_title",
    "薪资": "salary",
    "城市": "city",
    "区域": "district",
    "经验": "experience",
    "学历": "education",
    "公司": "company",
    "公司领域": "company_field",
    "公司性质": "company_type",
    "公司规模": "company_size",
    "公司详情页": "company_detail_url",
    "职位详情页": "job_detail_url"
}

def save_to_mysql(data_dict):
    """保存数据到MySQL数据库"""
    try:
        conn = pymysql.connect(**DB_CONFIG)
        cursor = conn.cursor()
        
        # 插入数据的SQL语句（字段名用英文）
        insert_sql = """
        INSERT INTO crawler_py_c (job_title, salary, city, district, experience, education, company, company_field, company_type, company_size, company_detail_url, job_detail_url)
        VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
        """
        
        # 用中文字段名取值，顺序与SQL一致
        cursor.execute(insert_sql, (
            data_dict['职位'],
            data_dict['薪资'],
            data_dict['城市'],
            data_dict['区域'],
            data_dict['经验'],
            data_dict['学历'],
            data_dict['公司'],
            data_dict['公司领域'],
            data_dict['公司性质'],
            data_dict['公司规模'],
            data_dict['公司详情页'],
            data_dict['职位详情页']
        ))
        
        conn.commit()
        cursor.close()
        conn.close()
        return True
        
    except Exception as e:
        print(f"保存到MySQL时出错: {e}")
        return False

# 创建文件对象（保留CSV输出作为备份）
if CRAWLER_CONFIG['save_csv']:
    f = open(CSV_CONFIG['qcwy_c_file'], mode='w', encoding='utf-8', newline='')
    # 字典写入方式 fieldnames->字段名根据提取到数据(保存字典)中键
    csv_writer = csv.DictWriter(f, fieldnames=[
        '职位',
    '薪资',
    '城市',
    '区域',
    '经验',
    '学历',
    '公司',
    '公司领域',
    '公司性质',
    '公司规模',
    '公司详情页',
    '职位详情页',
    ])
    # 写入表头
    csv_writer.writeheader()


# 打开浏览器 (实例化浏览器对象)
dp = ChromiumPage()
# 访问网站
dp.get(TARGET_URL_C)

# 统计变量
total_count = 0
success_count = 0

# 构建循环翻页
for page in range(1, CRAWLER_CONFIG['max_pages'] + 1):
    print(f'正在采集C/C++职位第{page}页的数据内容')
    # 下滑网页操作
    dp.scroll.to_bottom()
    """解析数据"""
    # 第一次提取, 提取所有职位信息所在div标签
    divs = dp.eles('css:.joblist-item')
    # for循环遍历, 提取列表里面元素
    for div in divs:
        """提取具体职位信息内容"""
        # 提取json字符串数据(职位部分信息)
        info = div.ele('css:.joblist-item-job').attr('sensorsdata')
        # 把json字符串转成json字典数据
        json_data = json.loads(info)
        # 提取职位详情页
        job_link = f'https://jobs.51job.com/shanghai-ypq/{json_data["jobId"]}.html'
        # 提取公司名 字符串方法 strip() 去除左右两端空格
        c_name = div.ele('css:.cname').text.strip()
        # 公司详情页
        c_link = div.ele('css:.cname').attr('href')
        # 公司信息
        c_info = [i.text for i in div.eles('css:.dc')]
        # 安全获取公司信息，避免索引越界
        if len(c_info) >= 1:
            company_field = c_info[0]
        else:
            company_field = ''
        
        if len(c_info) >= 2:
            company_nature = c_info[1]
        else:
            company_nature = ''
        
        # 判断是否有公司规模数据
        if len(c_info) >= 3:
            c_num = c_info[2]
        else:
            c_num = ''
        # 分割城市数据 split('·')字符串分割方法 ->
        # '广州·白云区' -> ['广州', '白云区']
        # '广州' -> ['广州']
        AreaInfo = json_data['jobArea'].split('·')
        # 判断城市元素个数
        if len(AreaInfo) == 2:
            city = AreaInfo[0]
            area = AreaInfo[1]
        else:
            city = AreaInfo[0]
            area = '未知'
        # 通过键值对取值, 提取相关信息, 保存字典中
        dit = {
            '职位': json_data['jobTitle'],
            '薪资': json_data['jobSalary'],
            '城市': city,
            '区域': area,
            '经验': json_data['jobYear'],
            '学历': json_data['jobDegree'],
            '公司': c_name,
            '公司领域': company_field,
            '公司性质': company_nature,
            '公司规模': c_num,
            '公司详情页': c_link,
            '职位详情页': job_link,
        }
        
        # 保存到CSV文件
        if CRAWLER_CONFIG['save_csv']:
            csv_writer.writerow(dit)
        
        # 保存到MySQL数据库
        if CRAWLER_CONFIG['save_mysql']:
            if save_to_mysql(dit):
                success_count += 1
                print(f"✓ 成功保存到MySQL: {dit['职位']} - {dit['公司']}")
            else:
                print(f"✗ 保存到MySQL失败: {dit['职位']} - {dit['公司']}")
        
        total_count += 1

    # 定位下一页按钮位置, 并进行点击
    dp.ele('css:.el-icon-arrow-right').click()

# 关闭文件
if CRAWLER_CONFIG['save_csv']:
    f.close()

print(f"\nC/C++职位数据采集完成！")
print(f"总计采集: {total_count} 条数据")
if CRAWLER_CONFIG['save_mysql']:
    print(f"成功保存到MySQL: {success_count} 条数据")
if CRAWLER_CONFIG['save_csv']:
    print(f"CSV文件已保存到: {CSV_CONFIG['qcwy_c_file']}")
print(f"MySQL数据库: crawler_py.crawler_py_c") 